package com.dongrj.framework.core.utils;

import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * @author dongrongjun
 * @date 2020/08/04
 */
@Slf4j
public final class ObjectUtils {

    /**
     * 只要任何一方等于null则相等
     *
     * @param object1 目标对象
     * @param object2 对比值
     */
    public static boolean checkDataEquals(Object object1, Object object2) {
        if (object1 == null) {
            return true;
        }
        if (object2 == null) {
            return true;
        }
        return object1.toString().equals(object2.toString());
    }


    /**
     * 对象为空返回默认值(defaultValue不能有计算)
     *
     * @param object       目标对象
     * @param defaultValue 默认值
     */
    public static <T, S extends T> T defaultIfNull(T object, S defaultValue) {
        return isNull(object) ? defaultValue : object;
    }


    /**
     * 对象为空返回默认值(defaultValue能有计算)
     *
     * @param object   目标对象
     * @param supplier 默认值Supplier
     */
    public static <T, S extends T> T defaultIfNull(T object, Supplier<S> supplier) {
        return isNull(object) ? supplier.get() : object;
    }

    /**
     * 条件为True返回默认值(defaultValue不能有计算)
     *
     * @param flag         条件
     * @param value        真实值
     * @param defaultValue 默认值
     */
    public static <T, S extends T> T defaultIfTrue(boolean flag, S value, S defaultValue) {
        if (flag) {
            return defaultValue;
        }
        return value;
    }

    /**
     * 条件为True返回默认值(defaultValue能有计算)
     *
     * @param flag                 条件
     * @param valueSupplier        真实值Supplier
     * @param defaultValueSupplier 默认值Supplier
     */
    public static <T, S extends T> T defaultIfTrue(boolean flag, Supplier<S> valueSupplier, Supplier<S> defaultValueSupplier) {
        if (flag) {
            return defaultValueSupplier.get();
        }
        return valueSupplier.get();
    }

    /**
     * 条件为False返回默认值(value,defaultValue不能有计算)
     *
     * @param flag         条件
     * @param value        真实值
     * @param defaultValue 默认值
     */
    public static <T, S extends T> T defaultIfFalse(boolean flag, S value, S defaultValue) {
        return defaultIfTrue(!flag, value, defaultValue);
    }

    /**
     * 条件为False返回默认值(value,defaultValue能有计算)
     *
     * @param flag                 条件
     * @param valueSupplier        真实值
     * @param defaultValueSupplier 默认值
     */
    public static <T, S extends T> T defaultIfFalse(boolean flag, Supplier<S> valueSupplier, Supplier<S> defaultValueSupplier) {
        return defaultIfTrue(!flag, valueSupplier.get(), defaultValueSupplier.get());
    }


    /**
     * 条件为True返回默认值
     *
     * @param flag            条件
     * @param function        真实值
     * @param defaultFunction 默认值
     */
    public static <R, T> R defaultIfTrue(boolean flag, T param, Function<T, R> function, Function<T, R> defaultFunction) {
        if (flag) {
            return defaultFunction.apply(param);
        }
        return function.apply(param);
    }

    /**
     * 条件为True返回默认值
     *
     * @param flag            条件
     * @param function        真实值
     * @param defaultFunction 默认值
     */
    public static <R, T> R defaultIfFalse(boolean flag, T param, Function<T, R> function, Function<T, R> defaultFunction) {
        return defaultIfTrue(!flag, param, function, defaultFunction);
    }


    /**
     * 判断对象是否都是空 (不能同时判断有关联对象如:user,user.getUserName())
     *
     * @param objects 对象集合
     */
    public static boolean isAllNull(Object... objects) {
        if (objects == null) {
            return true;
        }
        for (Object object : objects) {
            if (!isEmpty(object)) {
                return false;
            }
        }
        return true;
    }


    /**
     * 判断任何对象对象都不是空
     *
     * @param objects 对象集合
     */
    public static boolean isAnyNotNull(Object... objects) {
        if (objects == null || objects.length == 0) {
            return false;
        }
        for (Object object : objects) {
            if (isEmpty(object)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 获取条件值
     *
     * @param trueValue  true时值
     * @param falseValue false时值
     */
    public static <T> T value(boolean flag, T trueValue, T falseValue) {
        if (flag) {
            return trueValue;
        }
        return falseValue;
    }

    /**
     * 判断对象为空
     *
     * @param object 对象
     */
    public static boolean isNull(Object object) {
        return object == null;
    }

    /**
     * 判断对象为空
     *
     * @param obj 对象
     */
    public static boolean isEmpty(Object obj) {
        if (obj == null) {
            return true;
        }
        if (obj instanceof String) {
            return ((String) obj).length() == 0;
        }
        if (obj instanceof Collection) {
            return ((Collection) obj).isEmpty();
        }
        if (obj.getClass().isArray()) {
            return Array.getLength(obj) == 0;
        }
        if (obj instanceof Map) {
            return ((Map) obj).isEmpty();
        }
        return false;
    }

    /**
     * 判断对象为空
     *
     * @param obj 对象
     */
    public static boolean isNotEmpty(Object obj) {
        return !isEmpty(obj);
    }


    /**
     * 判断对象非空
     *
     * @param object 对象
     */
    public static boolean nonNull(Object object) {
        return !isNull(object);
    }


    /**
     * 数字转Long
     *
     * @param object  对象
     * @param dfValue 默认值
     */
    public static Long castLong(Object object, Long dfValue) {
        return cast(object, Long.class, dfValue);
    }


    /**
     * 数字转String
     *
     * @param object 对象
     */
    public static String castString(Object object) {
        return cast(object, String.class, "");
    }

    /**
     * 数字转String
     *
     * @param object  对象
     * @param dfValue 默认值
     */
    public static String castString(Object object, String dfValue) {
        return cast(object, String.class, dfValue);
    }


    /**
     * 对象转换
     *
     * @param object  对象
     * @param tClass  目标类型
     * @param dfValue 默认值
     */
    public static <T> T cast(Object object, Class<T> tClass, T dfValue) {
        if (isEmpty(object)) {
            return dfValue;
        }
        if (String.class.equals(tClass)) {
            String string = object.toString();
            return (T) string;
        }
        if (isClass(object, tClass)) {
            return (T) object;
        }
        return dfValue;
    }

    /**
     * 对象转换
     *
     * @param object 对象
     * @param tClass 目标类型
     */
    public static <T> T cast(Object object, Class<T> tClass) {
        return cast(object, tClass, null);
    }

    /**
     * 数字转Integer
     *
     * @param object  对象
     * @param dfValue 默认值
     */
    public static Integer castInteger(Object object, Integer dfValue) {
        return cast(object, Integer.class, dfValue);
    }


    public static <T> boolean isClass(Object object, Class<T> cls) {
        if (isNull(object)) {
            return false;
        }
        return object.getClass().equals(cls);
    }

    /**
     * 对象转String
     *
     * @param object  对象
     * @param dfValue 默认值
     */
    public static String toString(Object object, String dfValue) {
        if (isEmpty(object)) {
            return dfValue;
        }
        return object.toString();
    }


    /**
     * 数字转Integer(失败null)
     *
     * @param object 对象
     */
    public static Integer castInteger(String object) {
        return castInteger(object, null);
    }

    /**
     * 判断数字为空或等于零
     *
     * @number 数字
     */
    public static boolean greaterThanZero(Integer number) {
        if (isNull(number)) {
            return false;
        }
        return number.compareTo(0) > 0;
    }


    /**
     * @param object 对象
     * @param cls    目标具体类型
     * @param <T>    返回类型
     */
    public static <T, V extends T> T defaultIfNull(Object object, Class<T> cls, V v) {
        if (isNull(object)) {
            return v;
        }
        if (object.getClass().equals(cls)) {
            return (T) object;
        }
        return v;
    }

    /**
     * 判断是否基础类型
     *
     * @param model base
     */
    public static <Model> boolean isBaseType(Model model) {
        if (model instanceof String) {
            return true;
        }
        if (model instanceof Integer) {
            return true;
        }
        if (model instanceof Long) {
            return true;
        }
        if (model instanceof BigDecimal) {
            return true;
        }
        return false;
    }


}
